package com.foreveross.fetl.application.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.foreveross.fetl.application.ICabinGradeApplication;
import com.foreveross.fetl.application.IFlightInfoApplication;
import com.foreveross.fetl.application.ILpFreightApplication;
import com.foreveross.fetl.common.application.BaseApplicationImpl;
import com.foreveross.fetl.core.domain.freight.hbase.AgentEntity;
import com.foreveross.fetl.core.domain.freight.hbase.CabinEntity;
import com.foreveross.fetl.core.domain.freight.hbase.ReturnTripEntity;
import com.foreveross.fetl.core.domain.freight.hbase.TransitchangeEntity;
import com.foreveross.fetl.core.domain.freight.hbase.pre.LpFreightEntity;
import com.foreveross.fetl.core.domain.task.FreightPublishEntity;
import com.foreveross.fetl.core.domain.task.SourceEntity;
import com.foreveross.fetl.util.DateUtils;
import com.foreveross.fetl.util.RandomUtils;
import com.foreveross.fetl.vo.FlightInfoVO;
import com.foreveross.fetl.vo.cabin.CabinGradeVO;
import com.foreveross.fetl.vo.cabin.CabinSubVO;

@Transactional
@Service("lpFreightApplication")
public class LpFreightApplicationImpl extends BaseApplicationImpl implements
		ILpFreightApplication {
	private Logger log = Logger.getLogger(LpFreightApplicationImpl.class);
	@Inject
	private ICabinGradeApplication cabinGradeApplication;
	@Inject
	private IFlightInfoApplication flightInfoApplication;
	@Override
	public void randomFreight(Long channelId) {
		//获得所有的航班号
		List<SourceEntity> allSource = this.queryChannel2().queryResult("from SourceEntity", new Object[]{});
		ExecutorService es = Executors.newFixedThreadPool(allSource.size());
		List<String> results = new ArrayList<String>();
		List<Future<String>> futures = new ArrayList<Future<String>>();
		Future<String> future=null;
		List<FreightPublishEntity> allPublishPrice = this.queryChannel2().queryResult("from FreightPublishEntity", new Object[]{});
		List<CabinGradeVO> allCabinGrade = cabinGradeApplication.listAll();
		
		Map<Long, List<CabinGradeVO>> allCabin = this.getChannelCabins(allCabinGrade);
		Map<String, Long> allStandardPrice = this.getFeightPublishPrice(allPublishPrice);
		Map<String, SourceEntity> allAirCompany = this.getAllAirCompany(allSource);
		allPublishPrice = null;
		SourceEntity singleSource = null;
		if(channelId != null) singleSource = this.getSourceEntity(allSource, channelId);
		if(singleSource == null){
			for(SourceEntity se : allSource){//将不同的渠道拆分成不同的线程去做任务
				future= es.submit(new GenerateData(se, allStandardPrice, allAirCompany,allCabin.get(se.getId())));
				futures.add(future);
			}
		}else{
			future= es.submit(new GenerateData(singleSource, allStandardPrice, allAirCompany,allCabin.get(singleSource.getId())));
			futures.add(future);
		}
		for(Future<String> f : futures){
			try {
				results.add(f.get());
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
	}
	private SourceEntity getSourceEntity(List<SourceEntity> allSource, Long channelId){
		for(SourceEntity se : allSource){
			if(se.getId() == channelId) return se;
		}
		return null;
	}
	//舱位数据整合
	private Map<Long, List<CabinGradeVO>> getChannelCabins(List<CabinGradeVO> allCabinGrade){
		Map<Long, List<CabinGradeVO>> allCabin = new HashMap<Long, List<CabinGradeVO>>();
		for(CabinGradeVO vo : allCabinGrade){
			if(allCabin.get(vo.getChannelId()) == null)
				allCabin.put(vo.getChannelId(), new ArrayList<CabinGradeVO>());
			
			allCabin.get(vo.getChannelId()).add(vo);
		}
		return allCabin;
	}
	//标准运价整合
	private Map<String, Long> getFeightPublishPrice(List<FreightPublishEntity> allPublishPrice){
		Map<String, Long> allPrice = new HashMap<String, Long>();
		for(FreightPublishEntity e : allPublishPrice){
			allPrice.put(e.getFromCity()+"_"+e.getToCity(), e.getStandardPrice());
		}
		return allPrice;
	}
	//航空公司
	private Map<String, SourceEntity> getAllAirCompany(List<SourceEntity> allSource){
		Map<String, SourceEntity> allAirCompany = new HashMap<String, SourceEntity>();
		for(SourceEntity e : allSource){
			if(e.getWebTyle().equals("1")) allAirCompany.put(e.getHbaseKey(), e);
		}
		return allAirCompany;
	}
	class GenerateData implements Callable<String> {
		private SourceEntity se;
		private Map<String, Long> allStandardPrice;
		private Map<String, SourceEntity> allAirCompany;
		private List<CabinGradeVO> channelCabins;
        public GenerateData(SourceEntity se,Map<String, Long> allStandardPrice,
        		Map<String, SourceEntity> allAirCompany,List<CabinGradeVO> channelCabins){
        	this.se = se;
        	this.allStandardPrice = allStandardPrice;
        	this.allAirCompany = allAirCompany;
        	this.channelCabins = channelCabins;
        }
		@Override
		public String call()
				throws Exception {
			List<FlightInfoVO> flights = null;
			if(se.getWebTyle().equalsIgnoreCase("0")){
				flights = flightInfoApplication.listAll();
			}else{
				flights = flightInfoApplication.listByCompanyCode(se.getCarrierKey());
			}
			
			List<LpFreightEntity> results = null;
			try{
				if(flights != null && !flights.isEmpty()){
					for(FlightInfoVO e : flights){
						results = this.buildDatas(e);
						for(LpFreightEntity l : results){
							log.info("insert into : "+l.generateRowKey());
							l.create();
						}
					}
				}
			}finally{
				flights = null;
			}
			return null;
		}
		
		private List<LpFreightEntity> buildDatas(FlightInfoVO e){
			List<LpFreightEntity> results = new ArrayList<LpFreightEntity>();
			for(int i = 0 ;i < 30; i++){
				String currentDate = DateUtils.format(org.apache.commons.lang3.time.DateUtils
						.addDays(new Date(), i), "yyyy-MM-dd");
				if(se.getWebTyle().equals("0")){
					for(SourceEntity airCompany : allAirCompany.values()){
						results.add(this.buildFreightEntity(airCompany, e, currentDate));
					}
				}else{
					results.add(this.buildFreightEntity(se, e, currentDate));
				}
			}
			return results;
		}
		
		private LpFreightEntity buildFreightEntity(SourceEntity airCompany, 
				FlightInfoVO e, String currentDate){
				LpFreightEntity entity = new LpFreightEntity();
				entity.setAreaCode(e.getAreaCode());
				entity.setAreaName(e.getAreaName());
				
				entity.setCarrierFullName(airCompany.getName());
				entity.setCarrierKey(airCompany.getCarrierKey());
				entity.setCarrierName(airCompany.getShortName());
				entity.setCreateTime(new Date());
				if(StringUtils.isNotBlank(e.getEndTime())){
					entity.setEndTime(DateUtils.parse(currentDate+" "+e.getEndTime(), "yyyy-MM-dd HH:mm"));
				}
				entity.setFlightDate(currentDate);
				entity.setFlightNo(e.getFlightNo());
				entity.setFromCity(e.getFromCity());
				entity.setFromCityName(e.getFromCityName());
				entity.setToCity(e.getToCity());
				entity.setToCityName(e.getToCityName());
				entity.setGrabChannel(se.getName());
				entity.setGrabChannelId(se.getId());
				entity.setAttachHbaseKey(se.getHbaseKey());

				entity.setInterlinePrice(this.getInterlineRandomPrice(e));
				entity.setRoundTripPrice(this.getRoundTripPriceRandomPrice(e));
				
				entity.setStartTime((DateUtils.parse(currentDate+" "+e.getStartTime(), "yyyy-MM-dd HH:mm")));
				entity.setType("波音632");
				
				entity.getCabins().addAll(buildCabinEntity(e));
				//设置代理商
				if(se.getWebTyle().equals("0")){
					
					entity.getAgents().addAll(this.buildAgentEntity(e, airCompany));
					
					AgentEntity lowerAgent = getLowerPrice(entity.getAgents());
					AgentEntity highAgent = getHighPrice(entity.getAgents());
					if(lowerAgent != null) entity.setAreaName(lowerAgent.getName());

					if(lowerAgent != null) entity.setLowerPrice(lowerAgent.getPrice());
					else entity.setLowerPrice(this.getLowerRandomPrice(e));
					
					if(lowerAgent != null) entity.setHighPrice(highAgent.getPrice());
					else entity.setHighPrice(entity.getLowerPrice());
				}else{
					entity.setHighPrice(getHighRandomPrice(e));
					entity.setLowerPrice(this.getLowerRandomPrice(e));
				}
			return entity;
		}
		//最低价
		private AgentEntity getLowerPrice(Set<AgentEntity> agents){
			AgentEntity temp = null;
			for(AgentEntity e : agents){
				if(temp == null){ temp = e;continue;}
				if(e.getPrice() < temp.getPrice()) temp = e;
			}
			return temp;
		}
		//最高价
		private AgentEntity getHighPrice(Set<AgentEntity> agents){
			AgentEntity temp = null;
			for(AgentEntity e : agents){
				if(temp == null){ temp = e;continue;}
				if(e.getPrice() > temp.getPrice()) temp = e;
			}
			return temp;
		}
		private Double getHighRandomPrice(FlightInfoVO e){
			Long price = allStandardPrice.get(e.getFromCity()+"_"+e.getToCity());
			if(price == null || price <= 0) price = 100l;
			return new Double(RandomUtils.nextRandom(Integer.valueOf(price.toString()),
					Integer.valueOf(price.toString())*2));
		}
		private Double getLowerRandomPrice(FlightInfoVO e){
			Long price = allStandardPrice.get(e.getFromCity()+"_"+e.getToCity());
			if(price == null || price <= 0) price = 100l;
			return new Double(RandomUtils.nextRandom(50,
					Integer.valueOf(price.toString())));
		}
		private Double getInterlineRandomPrice(FlightInfoVO e){
			Long price = allStandardPrice.get(e.getFromCity()+"_"+e.getToCity());
			if(price == null || price <= 0) price = 100l;
			int min = (int)(Integer.valueOf(price.toString())*1.5);
			int max = (int)(Integer.valueOf(price.toString())*2.5);
			return new Double(RandomUtils.nextRandom(min,
					max));
		}
		private Double getRoundTripPriceRandomPrice(FlightInfoVO e){
			Long price = allStandardPrice.get(e.getFromCity()+"_"+e.getToCity());
			if(price == null || price <= 0) price = 100l;
			int min = (int)(Integer.valueOf(price.toString())*1.5);
			int max = (int)(Integer.valueOf(price.toString())*3.5);
			return new Double(RandomUtils.nextRandom(min,
					max));
		}
		private List<CabinEntity> buildCabinEntity(FlightInfoVO e){
			List<CabinEntity> results = new ArrayList<CabinEntity>();
			//设置舱位价格
			for(CabinGradeVO cb : channelCabins){
				if(cb.getSubCabins() != null && !cb.getSubCabins().isEmpty()){
					for(CabinSubVO sub : cb.getSubCabins()){
						CabinEntity cabin = new CabinEntity();
						cabin.setCabinType(cb.getName());
						cabin.setProductName(sub.getName());
						cabin.setSubCabinName(sub.getName());
						cabin.setPrice(getLowerRandomPrice(e));
						results.add(cabin);
					}
				}else{
					CabinEntity cabin = new CabinEntity();
					cabin.setCabinType(cb.getName());
					cabin.setProductName(cb.getName());
					cabin.setPrice(getLowerRandomPrice(e));
					results.add(cabin);
				}
			}
			return results;
		}
		private List<AgentEntity> buildAgentEntity(FlightInfoVO e,SourceEntity airCompany){
			List<AgentEntity> results = new ArrayList<AgentEntity>();
			for(String n : ALL_AGENTNAMES){
				AgentEntity agent = new AgentEntity();
				agent.setName(n);
				agent.setType(1);
				agent.setOriginalPrice(getHighRandomPrice(e));
				agent.setPrice(agent.getOriginalPrice());
				results.add(agent);
			}
			//加一个直营的
			AgentEntity agent = new AgentEntity();
			agent.setName("直营"+airCompany.getName());
			agent.setType(0);
			agent.setOriginalPrice(getHighRandomPrice(e));
			agent.setPrice(agent.getOriginalPrice());
			results.add(agent);
			
			return results;
		}
		private List<ReturnTripEntity> buildReturnTripEntity(FlightInfoVO e){
			return null;
		}
		private List<TransitchangeEntity> buildTransitchangeEntity(FlightInfoVO e){
			return null;
		}
	}
	
	private final static String[] ALL_AGENTNAMES = {"达志成旅行","联丰航空","佳程票务",
		"柏银商务","华夏之旅","飞哪旅行网","上海之星","深圳华正商旅","东方祥云航空","南联信航空"};
}

